package top.maof.book.service.myImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import top.maof.book.params.BooksParam;
import top.maof.book.annotation.CacheExpire;
import top.maof.book.dao.BookMapper;
import top.maof.book.model.Book;
import top.maof.book.result.PageData;
import top.maof.book.result.PageWrap;
import top.maof.book.search.Search;
import top.maof.book.service.BookService;
import top.maof.book.utils.Utils;
import top.maof.book.vo.PageVo;

import java.util.List;
import java.util.Map;

@Service("bookServiceImpl")
@Slf4j
//@CacheConfig(cacheNames = {"book"})
public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements BookService {

    @Cacheable(value = "book", key = "methodName+'::'+#sourceSite")
    @CacheExpire()
    @Override
    public List<String> classifies(String sourceSite) {
        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
        queryWrapper = queryWrapper.select("DISTINCT classify");
        queryWrapper.lambda().eq(sourceSite != null && !"".equals(sourceSite), Book::getSourceSite, sourceSite);
        return listObjs(queryWrapper, String::valueOf);
    }

    @Override
    public PageData<Book> findPage(PageWrap<Book> pageWrap) {

        IPage<Book> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());

        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
        Utils.MP.blankToNull(pageWrap.getModel());
        if (pageWrap.getModel().getId() != null) {
            queryWrapper.lambda().eq(Book::getId, pageWrap.getModel().getId());
        }
        if (pageWrap.getModel().getName() != null) {
            queryWrapper.lambda().eq(Book::getName, pageWrap.getModel().getName());
        }
        if (pageWrap.getModel().getAuthor() != null) {
            queryWrapper.lambda().eq(Book::getAuthor, pageWrap.getModel().getAuthor());
        }
        if (pageWrap.getModel().getImg() != null) {
            queryWrapper.lambda().eq(Book::getImg, pageWrap.getModel().getImg());
        }
        if (pageWrap.getModel().getSynopsis() != null) {
            queryWrapper.lambda().eq(Book::getSynopsis, pageWrap.getModel().getSynopsis());
        }
        if (pageWrap.getModel().getClassify() != null) {
            queryWrapper.lambda().eq(Book::getClassify, pageWrap.getModel().getClassify());
        }
        if (pageWrap.getModel().getState() != null) {
            queryWrapper.lambda().eq(Book::getState, pageWrap.getModel().getState());
        }
        if (pageWrap.getModel().getInsertDate() != null) {
            queryWrapper.lambda().ge(Book::getInsertDate, Utils.Date.getStart(pageWrap.getModel().getInsertDate()));
            queryWrapper.lambda().le(Book::getInsertDate, Utils.Date.getEnd(pageWrap.getModel().getInsertDate()));
        }
        if (pageWrap.getModel().getUpdateDate() != null) {
            queryWrapper.lambda().ge(Book::getUpdateDate, Utils.Date.getStart(pageWrap.getModel().getUpdateDate()));
            queryWrapper.lambda().le(Book::getUpdateDate, Utils.Date.getEnd(pageWrap.getModel().getUpdateDate()));
        }
        if (pageWrap.getModel().getSourceSite() != null) {
            queryWrapper.lambda().eq(Book::getSourceSite, pageWrap.getModel().getSourceSite());
        }
        if (pageWrap.getModel().getSourceUrl() != null) {
            queryWrapper.lambda().eq(Book::getSourceUrl, pageWrap.getModel().getSourceUrl());
        }
        if (pageWrap.getModel().getStartDate() != null) {
            queryWrapper.lambda().ge(Book::getStartDate, Utils.Date.getStart(pageWrap.getModel().getStartDate()));
            queryWrapper.lambda().le(Book::getStartDate, Utils.Date.getEnd(pageWrap.getModel().getStartDate()));
        }
        for (PageWrap.SortData sortData : pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
                queryWrapper.orderByDesc(sortData.getProperty());
            } else {
                queryWrapper.orderByAsc(sortData.getProperty());
            }
        }
        IPage<Book> bookIPage = bookMapper.selectPage(page, queryWrapper);
        return PageData.from(bookIPage);
    }

    @Autowired
    private BookMapper bookMapper;

    @Autowired
    private Search search;

    /**
     * 表中没有则添加,返回id
     * 表中有则直接返回id
     */
    @Transactional
    @Override
    public int add(Book book) throws Exception{
        Book book1 = bookMapper.selectByNameAndAuthor(book.getName(), book.getAuthor());
        if (book1 == null) {
            bookMapper.insert(book);
            search.write(book);
            return book.getId();
        } else {
            return book1.getId();
        }
    }

    @Override
    public Book selectByNameAndAuthor(String name, String author) {
        return bookMapper.selectByNameAndAuthor(name, author);
    }

    @Cacheable(value = "book", key = "methodName+':'+#id")
    @CacheExpire()
    @Override
    public Book find(int id) {
        return bookMapper.selectById(id);
    }

    @Override
    public int update(Book book) {
        return bookMapper.updateByPrimaryKeySelective(book);
    }

    @Override
    public int delete(int id) {
        return bookMapper.deleteByPrimaryKey(id);
    }

    @Override
    public List<Book> select(Map map) {
        return bookMapper.select(map);
    }

    @Override
    public int selectCount(Map map) {
        return bookMapper.selectCount(map);
    }

    @Override
    public List<Book> selectList(List list) {
        return bookMapper.selectList(list);
    }

    @Override
    public List<Book> selectByAuthor(String author) {
        return bookMapper.selectByAuthor(author);
    }

    @Override
    public PageVo<Book> list(BooksParam booksParam) {
        LambdaQueryWrapper<Book> lambdaQuery = Wrappers.<Book>lambdaQuery();
        lambdaQuery.eq(!StringUtils.isEmpty(booksParam.getName()), Book::getName, booksParam.getName());
        lambdaQuery.eq(!StringUtils.isEmpty(booksParam.getAuthor()), Book::getAuthor, booksParam.getAuthor());
        lambdaQuery.eq(!StringUtils.isEmpty(booksParam.getClassify()), Book::getClassify, booksParam.getClassify());
        lambdaQuery.eq(!StringUtils.isEmpty(booksParam.getState()), Book::getState, booksParam.getState());
        lambdaQuery.eq(!StringUtils.isEmpty(booksParam.getSourceSite()), Book::getSourceSite, booksParam.getSourceSite());
        IPage<Book> iPage = super.page(booksParam.iPage(), lambdaQuery);
        return new PageVo<Book>(iPage.getRecords(), iPage.getTotal());
    }

}
